/**
 * ex6. time包及日期函数
 *
 * @author cyy
 * @date 2020/11/4
 */
package main

import (
	"fmt"
	"time"
)

func main() {
	/*
		可以通过time.Now()获取当前时间
			time.Now().Year()
			time.Now().Month()
			time.Now().Day()
			time.Now().Hour()
			time.Now().Minute()
			time.Now().Second()
	*/
	fmt.Println("============================ time ============================")
	timeTmp := time.Now()
	fmt.Println(timeTmp) // 2020-11-04 13:09:32.1759897 +0800 CST m=+0.002927601

	// 使用format格式化
	//  注：go语言的格式化时间模板不是常见的Y-m-d H:M:S，而是go诞生时间（2006-01-02 15:04:05 -> 2006 1 2 3 4 5）
	formatDate1 := timeTmp.Format("2006-01-02 03:04:05") // 使用 03 表示采取12小时制
	fmt.Println(formatDate1)                             // 2020-11-04 01:09:32
	formatDate2 := timeTmp.Format("2006/01/02 15:04:05") // 使用 15 表示采取24小时制
	fmt.Println(formatDate2)                             // 2020/11/04 13:09:32

	/*
		时间戳
			自1970年1月1日（08:00:00 GMT）至当前时间的总秒数
	*/
	fmt.Println("\n============================ 时间戳 ============================")
	timeStamp := timeTmp.Unix()
	// 时间戳转日期
	// 	参数1：秒时间戳，参数2：纳秒时间戳
	t := time.Unix(timeStamp, 0)
	timeStr := t.Format("2006-01-02 15:04:05")
	fmt.Printf("时间戳[%d] 转 时间[%v]\n", timeStamp, timeStr) // 2020-11-04 13:09:32
	// 日期字符串转时间
	timeTmp, _ = time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local)
	fmt.Printf("日期字符串[%s] 转 时间[%v]、时间戳[%d]\n", timeStr, timeTmp, timeTmp.Unix())

	/*
		时间操作函数
			时间常量：time包中定义了许多常量，可以直接使用
				const (
					Nanosecond  Duration = 1
					Microsecond          = 1000 * Nanosecond
					Millisecond          = 1000 * Microsecond
					Second               = 1000 * Millisecond
					Minute               = 60 * Second
					Hour                 = 60 * Minute
				)
	*/
	fmt.Println("\n============================ 时间操作函数 ============================")
	timeTmp = timeTmp.Add(time.Hour)
	fmt.Println(timeTmp.Format("2006-01-02 15:04:05"))

	/*
		定时器
	*/
	// TODO: 2020/11/4 定时器的底层实现
	ticker := time.NewTicker(time.Second)
	n := 5
	for t := range ticker.C {
		n--
		fmt.Println(t)
		if n == 0 {
			ticker.Stop() // 终止定时器
			// 若此处不写break退出定时任务语句，会发生死锁：
			// 		fatal error: all goroutines are asleep - deadlock!
			//
			// 		goroutine 1 [chan receive]:
			// 		main.main()
			//		golang-learning/src/main/main.go:71 +0x869
			break
		}
	}

	// sleep 函数
	time.Sleep(time.Second * 3)

}
